#include <iostream>
#include <vector>
#include <string>
//#include "iostream"
#include<iomanip> 
#include <time.h>
#include "recursion.h"
#include <chrono>
#include <unordered_set>
#include<set>
#include<string.h>
#define setbit(x,y)  (x|=(1<<y)) //let the y bit be 1  
#define twosetbit(x,y,z) (x|=((1<<y)|(1<<z)))
#define clrbit(x,y)  (x&=~(1<<y)) //let the y bit be 0
#define twoclrbit(x,y,z) (x&=~((1<<y)|(1<<z)) )
#define reversebit(x,y)  (x^=(1<<y)) //reverse the y bit
#define getbit(x,y)   ((x) >> (y)&1) //get the y bit number begin with the 0 bit
#define getsigarraybit(a,b) (((*(a+((b&0xffffffe0)>>5))) >> ((b%32)))&1)
#define reversesigarraybit(a,b)  ((*(a+((b&0xffffffe0)>>5)))^=(1<<(b%32)))
using namespace std;
unsigned int RamdomArray[20];


unsigned int* Random32bit(int ArrayLength){
    //unsigned int i;
    //RamdomArray={0};
    memset(RamdomArray,0,20);
    int RemainPart=(int)(ArrayLength/32);
    srand(time(NULL));
    for(int j=0;j<(int)(ArrayLength/32);j++){
        RamdomArray[j]=rand()^(rand()<<15)^(rand()<<30);
    }
    if(ArrayLength%32<=15){
        RamdomArray[RemainPart]=(rand()>>(15-(ArrayLength%32)));
    }
    else if(ArrayLength%32<=30){
        RamdomArray[RemainPart]=rand()^((rand()>>(30-(ArrayLength%32)))<<15);
    }else{
        RamdomArray[RemainPart]=(rand()^(rand()<<15)^(rand()<<30))>>1;
    }
    return (unsigned int *)RamdomArray;

}
class KeyNumber
{
//unsigned int* PivotArray;
public:
unsigned int  aa[20];
static unsigned int NumberReturn[20];
//public:
  KeyNumber(/*unsigned int* PivotArray,*/unsigned  int *bb){
    for(int i=0;i<20;i++){
        aa[i]=bb[i];
        //cout<<aa[i];
    }
    //this->PivotArray=PivotArray;
    
  }
    unsigned int* GetAA()  const {
    /*for(int i=0;i<20;i++){
        NumberReturn[i]=aa[i];
        
    }*/
    //cout<<aa[0]<<aa[1];
   // cout<<"aaa";
    return(unsigned int*)aa;
  }
  bool operator<(const KeyNumber& w) const{
     for(int i=0;i<20;i++){
        if(w.aa[i]<aa[i]){
            return false;
        }
        if(w.aa[i]>aa[i]){
            return true;

        }
     }
     //return -1;
  }
  bool operator==(const unsigned int cc[20]){
     for(int i=0;i<20;i++){
        if(cc[i]!=aa[i]){
            return false;

        }
     }
     return true;

  }

};
//unordered_set<unsigned long long int [20]> Walk;
//unordered_set<KeyNumber> Walk1;
set<KeyNumber> walks;
/*struct DataSequence
{
    unsigned long long int data[20];

};*/
double CalculateEnergy(int ArrayLength,unsigned int *Array){
    int Autocorrelations=0;
    int Energy=0;
   for(int i=1;i<ArrayLength;i++){
       for(int j=0;j<ArrayLength-i;j++){
        
        if(((getsigarraybit(Array,j))^(getsigarraybit(Array,(j+i))))){
            Autocorrelations=Autocorrelations-2;
            
        }
     
        Autocorrelations=Autocorrelations+1;
       
       }
       Energy=Energy+Autocorrelations*Autocorrelations;
       Autocorrelations=0;
   }
   return Energy;
}
 void NewPivot_saw(/*int BitNumber,unsigned int*BitArray*/){
  /*unsigned int  BitNumberArray[BitNumber][20];
  for(int i=0;i<BitNumber;i++){
    //if(Walk1.find())

  }*/
  for(int i=9;i>=0;i--){
    unsigned int* kk=new unsigned int [20]();
    kk[0]=i;
    walks.insert(KeyNumber(kk));
    delete[] kk;
  }
  cout<<"number::"<<walks.size()<<endl;
  set<KeyNumber>::iterator it=walks.begin();
  unsigned int* kk;
  while (it!=walks.end())
  {
   kk=((*it).GetAA()) ;
   cout<<"number;;;"<<kk[0]<<kk[1]<<endl;
   it++;
    //cout<<kk[0];


  }
  


  

 }
 void testall(){
    unsigned int* i;
    i=Random32bit(60);
     cout<<"vvvv;;"<<hex<<i[0]<<";;;;"<<i[1]<<endl;
 }
